package example

import (
	"fmt"
	"io/ioutil"
	time2 "time"
)

var matches int

func findAll(path string) {
	start := time2.Now()
	search(path)
	fmt.Println(matches, "matches")
	fmt.Println(time2.Since(start))
}

func search(path string) {
	files, err := ioutil.ReadDir(path)
	if err == nil {
		for _, file := range files {
			if file.IsDir() {
				name := file.Name()
				search(path + name + "/")
			} else {
				matches++
			}
		}
	}
}

var workerCount = 0
var maxWorkerCount = 4
var searchRequest = make(chan string)
var workerDone = make(chan bool)
var foundMatch = make(chan bool)
var matchesBy int

func findAllByRoutine(path string) {
	start := time2.Now()
	workerCount = 1
	go searchBy(path, true)
	waitForWorkers()
	fmt.Println(matchesBy, "matches")
	fmt.Println(time2.Since(start))
}

func searchBy(path string, master bool) {
	files, err := ioutil.ReadDir(path)
	if err == nil {
		for _, file := range files {
			if file.IsDir() {
				name := file.Name()
				if workerCount < maxWorkerCount {
					searchRequest <- path + name + "/"
				} else {
					searchBy(path+name+"/", false)
				}
			} else {
				foundMatch <- true
			}
		}
	}
	if master {
		workerDone <- true
	}
}

func waitForWorkers() {
	for {
		select {
		case path := <-searchRequest:
			workerCount++
			go searchBy(path, true)
		case <-workerDone:
			workerCount--
			if workerCount == 0 {
				return
			}
		case <-foundMatch:
			matchesBy++
		}
	}
}
